<!--
  表具详情
    注意点: 1、模态框展示此组件时，当模态框关闭后，需要将传入此组件的 content 置为空置，这样避免画线出现警告。
-->

<template>
  <div :id="id" :key="id" class="user-meter-detail-wrap">
    <div class="detail-box-left">
      <e-tree :id="id + 'left'" :modal="true" :chartData="userTreeData" />
    </div>
    <div class="info">
      <div class="info-tit">用户信息</div>
      <div class="name" :ref="userInfoId" :id="userInfoId">{{ unitName }}</div>
      <div class="right-text-box">
        <div class="right-text info-tit" :ref="meterInfoId" :id="meterInfoId">表具信息</div>
      </div>
    </div>
    <div class="detail-box-right">
      <e-tree
        :id="id + 'right'"
        :modal="true"
        :chartData="meterTreeData"
        @q-click="rightETreeClickHandle"
        @q-finished="drawLine"
      />
    </div>
  </div>
</template>
<script>
import { each, forOwn, isArray, includes, toString, merge, isEmpty } from 'lodash'
import jsPlumb from 'jsplumb'
import { nanoid } from 'nanoid'
import { meterFilterData } from './meterFilterData'
import { eTreeOptions } from './chartOptions/index'

export default {
  name: 'userAndMeterDetailETree',
  props: {
    id: {
      type: String,
      default: nanoid()
    },
    content: {
      type: Object
    },
    currentMeterId: {
      type: String | Number
    }
  },
  data() {
    return {
      userTreeData: null,
      meterTreeData: {},
      unitName: '',
      ids: [],
      jsplumb: null,
      collapsedNames: 'meterId'
    }
  },
  computed: {
    userInfoId() {
      return this.id + '-user-info'
    },
    meterInfoId() {
      return this.id + '-meter-info'
    }
  },
  watch: {
    content: {
      handler() {
        this.modifyLeftToRightTreeData(this.content)
      },
      deep: true,
      immediate: true
    }
  },
  components: {
    ETree: () => import('@/commons/charts/ETree')
  },
  methods: {
    /**
     * desc: 获取节点所有id
     * param {type}
     * return: void
     */
    getIds(data) {
      const { children } = data
      const ids = []
      each(children, item => {
        ids.push(item.value)
      })
      this.ids = ids
    },
    /**
     * desc: 节点收缩
     * param {type}
     * return: void
     */
    collapseData(args, keys, data) {
      const {
        value,
        data: { collapsed }
      } = args
      if (includes(this.ids, value)) {
        const { children } = data
        each(children, item => {
          if (includes(keys, item.name) && item.value === value && collapsed) {
            item.collapsed = false
          } else {
            item.collapsed = true
          }
        })
        this.meterTreeData.series[0].data = [data]
      }
    },
    /**
     * desc: 右边树图节点点击
     * param {type}
     * return: void
     */
    rightETreeClickHandle(params) {
      const _currentData = this.meterTreeData.series[0].data[0]
      this.getIds(_currentData)
      let names = this.collapsedNames
      if (!isArray(this.collapsedNames)) {
        names = [this.collapsedNames]
      }
      this.collapseData(params, names, _currentData)
    },
    /**
     * desc: 画连接线
     * param {type}
     * return: void
     */
    drawLine(chart, data) {
      if (isEmpty(this.content)) return
      const _this = this
      const { y } = data._itemLayouts[1]
      const textDom = _this.$refs[_this.meterInfoId]
      const textDomHeight = textDom.offsetHeight
      const retHeight = y - textDomHeight / 2 + 4
      textDom.style.top = retHeight + 'px'

      _this.$nextTick(() => {
        if (_this.jsplumb) {
          _this.jsplumb.reset()
          _this.jsplumb = null
        }
        _this.jsplumb = jsPlumb.jsPlumb.getInstance({
          Anchor: ['Right', 'Left'],
          Anchors: ['Right', 'Left'],
          ConnectionsDetachable: false,
          Connector: 'Straight',
          PaintStyle: {
            stroke: '#7da2e1'
          },
          ConnectorStyle: {
            stroke: '#7da2e1'
          },
          EndpointStyle: {
            radius: 4,
            fillStyle: '#ffffff'
          }
        })
        _this.jsplumb.ready(function() {
          _this.jsplumb.connect({
            source: _this.userInfoId,
            target: _this.meterInfoId,
            endpoint: 'Dot'
          })
        })
      })
    },
    /**
     * 用户树形信息整理data
     * @param  {[type]} data [description]
     * @return {[type]} 用户信息树形菜单
     */
    modifyUserTreeData(data = {}) {
      let userData = {
        name: 'userinfo',
        children: null
      }
      const { userInfoKyes = [] } = meterFilterData
      const userDataChild = []
      each(userInfoKyes, item => {
        const val = data[item]
        if (val) {
          userDataChild.push({
            name: item,
            value: val
          })
        }
      })
      userData.children = userDataChild
      this.userTreeData = merge({}, eTreeOptions, {
        series: [
          {
            orient: 'RL',
            right: 0,
            left: '5%',
            leaves: {
              label: {
                position: 'top',
                verticalAlign: 'top'
              }
            },
            data: [userData]
          }
        ]
      })
    },
    /**
     * 表具树形信息整理
     * @param  {[type]} arr [description]
     * @return {[type]} 表具信息树形菜单
     */
    modifyMeterTreeData(arr) {
      let retData = {}
      const retChild = []
      const { rtuIdKeys, addressInfoKeys, meterInfoKeys } = meterFilterData

      each(arr, item => {
        const currentData = {}
        const currentChild = []
        const addressData = {
          name: 'addressInfo',
          children: null,
          value: null
        }
        const addressChild = []
        const meterInfoData = {}
        const meterInfoChild = []
        const { meterId, rtuId, modelNo, ...rest } = item
        meterInfoData.name = 'modelNo'
        meterInfoData.value = modelNo
        currentData.name = 'meterId'
        currentData.value = meterId
        forOwn(rest, (val, key) => {
          if (includes(addressInfoKeys, key)) {
            addressChild.push({
              name: key,
              value: val,
              parendId: meterId
            })
          } else if (includes(meterInfoKeys, key)) {
            meterInfoChild.push({
              name: key,
              value: val,
              parendId: meterId
            })
          } else {
            currentChild.push({
              name: key,
              value: val,
              parendId: meterId
            })
          }
        })
        meterInfoData.children = meterInfoChild
        addressData.children = addressChild
        currentChild.push(meterInfoData, addressData)
        const { rtuId: rtId, ...args } = rtuId

        const rtChild = []
        each(rtuIdKeys, rt => {
          rtChild.push({
            name: rt,
            value: args[rt]
          })
        })

        currentChild.push({
          name: 'rtuId',
          value: rtId,
          children: rtChild
        })
        currentData.children = currentChild

        retChild.push(currentData)
      })

      each(retChild, item => {
        const { value, children } = item
        if (toString(this.currentMeterId) !== toString(value)) {
          this.addCollapsed(children, false)
          item.collapsed = true
        } else {
          this.addCollapsed(children, false)
          item.collapsed = false
        }
      })
      retData.children = retChild

      this.meterTreeData = merge({}, eTreeOptions, {
        series: [
          {
            left: '0',
            data: [retData]
          }
        ]
      })
    },
    /**
     * @msg: 节点是狗折叠
     * @param {type}
     * @return:
     */
    addCollapsed(data, flag = false) {
      each(data, item => {
        const { children } = item
        if (children && isArray(children)) {
          this.addCollapsed(children, flag)
        }
        item.collapsed = flag
      })
    },
    /**
     * 树形菜单数据处理
     * @param  {[type]} treeData [description]
     * @return {[type]}            [description]
     */
    modifyLeftToRightTreeData(treeData = {}) {
      const { children, unitName, ...rest } = treeData
      this.modifyUserTreeData(rest)
      this.modifyMeterTreeData(children)
      this.unitName = unitName
    }
  }
}
</script>
<style lang="less" scoped>
@import './index.less';
</style>
